package io.terminus.paas.profiler.service.impl

import com.alibaba.dubbo.common.Constants
import com.alibaba.dubbo.common.utils.StringUtils
import io.terminus.paas.profiler.AbstractProfilerService
import io.terminus.paas.profiler.model.Configuration
import io.terminus.paas.profiler.model.DubboProvider
import io.terminus.paas.profiler.service.ConfigurationService
import io.terminus.paas.profiler.utils.sync.SyncUtils
import io.terminus.paas.profiler.model.Provider
import io.terminus.paas.profiler.service.ProviderService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

/**
 * Created by gengrong on 16/3/18.
 */
@Service
class ProviderServiceImpl @Autowired constructor(
        private val configurationService: ConfigurationService
) : ProviderService, AbstractProfilerService() {
    override fun enableProvider(registryAddress: String, providerId: Long) {
        val oldProvider = findProviderById(registryAddress, providerId) ?: throw IllegalStateException("Provider was changed!")

        if (oldProvider.dynamic) {
            //保证disable的override唯一
            if (!oldProvider.enabled) {
                val configuration = Configuration()
                configuration.address = oldProvider.address
                configuration.service = oldProvider.service
                configuration.enabled = true
                configuration.params = Constants.DISABLED_KEY + "=false"
                configurationService.saveConfiguration(registryAddress, configuration)
                return
            }
            val oList = configurationService.findByServiceAndAddress(registryAddress, oldProvider.service!!, oldProvider.address!!)

            for (o in oList) {
                val params = StringUtils.parseQueryString(o.params)
                if (params.containsKey(Constants.DISABLED_KEY)) {
                    if (params[Constants.DISABLED_KEY] == "true") {
                        configurationService.deleteConfiguration(registryAddress, o.id!!)
                    }
                }
            }
        } else {
            oldProvider.enabled = true
            updateProvider(registryAddress, oldProvider)
        }
    }

    override fun disableProvider(registryAddress: String, providerId: Long) {
        val oldProvider = findProviderById(registryAddress, providerId)
        oldProvider ?: throw IllegalStateException("Provider was changed!")
        if (oldProvider.dynamic) {
            //保证disable的override唯一
            if (oldProvider.enabled) {
                val configuration = Configuration()
                configuration.address = oldProvider.address
                configuration.service = oldProvider.service
                configuration.enabled = true
                configuration.params = Constants.DISABLED_KEY + "=true"
                configurationService.saveConfiguration(registryAddress, configuration)
                return
            }
            val oList = configurationService.findByServiceAndAddress(registryAddress, oldProvider.service!!, oldProvider.address!!)

            for (o in oList) {
                val params = StringUtils.parseQueryString(o.params)
                if (params.containsKey(Constants.DISABLED_KEY)) {
                    if (params[Constants.DISABLED_KEY] == "false") {
                        configurationService.deleteConfiguration(registryAddress, o.id!!)
                    }
                }
            }
        } else {
            oldProvider.enabled = false
            updateProvider(registryAddress, oldProvider)
        }

    }

    override fun deleteProvider(registryAddress: String, providerId: Long) {
        throw UnsupportedOperationException()
    }

    override fun findProviderByServiceId(registryAddress: String, serviceId: String): List<Provider> {
        val ret = arrayListOf<Provider>();
        getProviderUrls(registryAddress)[serviceId]?.forEach {
            val provider = SyncUtils.url2Provider(it);
            if (provider != null) {
                ret.add(provider);
                getConfiguratorUrls(registryAddress)[serviceId]?.values?.forEach {
                    var disable = it.parameters[Constants.DISABLED_KEY];
                    if (disable?.toBoolean() ?: false) {
                        provider.enable = false;
                    }
                }
            }
        }
        return ret
    }

    override fun getDetailByProviderId(registryAddress: String, providerId: Long): Provider {
        throw UnsupportedOperationException()
    }

    private fun findProviderById(registryAddress: String, providerId: Long): DubboProvider? {
        //循环所有服务,并根据提供者ID匹配,返回首个匹配的Provider
        getProviderUrls(registryAddress).forEach {
            val url = it.value.entries.first { providerId == it.key }
            SyncUtils.url2Provider(url)?.let { return it }
        }
        return null
    }

    fun updateProvider(registryAddress: String, provider: DubboProvider) {
        val id = provider.id ?: throw IllegalStateException("no provider id")
        val oldProvider = findProviderById(registryAddress, id) ?: throw IllegalStateException("Provider was changed!")
        val newProvider = provider.toUrl()

        getRegistryService(registryAddress).unregister(oldProvider.toUrl())
        getRegistryService(registryAddress).register(newProvider)
    }
}